package com.zy.ipanalysis.controller;

import com.zy.ipanalysis.model.Ip;
import com.zy.ipanalysis.service.*;
import com.zy.commom.utils.IpUtil;
import com.zy.commom.utils.MailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.*;

/**
 * Created by ZYDR on 2015/12/27.
 */
@Controller
@RequestMapping("/ip")
public class IpController {
    private final static int VOLUME_INSERT_IP_NUMBER=600;
    private final static int VOLUME_INSERT_TIMES_NUMBER=1000;
    @Autowired
    IpService ipService;
    @Autowired
    IspMaskService ispMaskService;
    @Autowired
    IspService ispService;
    @Autowired
    DistrictService districtService;
    @Autowired
    InfService infService;
    @RequestMapping(value = "/queryByIp",method = RequestMethod.POST)
    public String queryByIp(Model model, @RequestParam("ip") String ip ){
        model.addAttribute("result",ipService.queryIspByIp(ip));
        model.addAttribute("ip",ip);
        return "index";
    }
    @RequestMapping("/import")
    public String importIp(Model model){
        String filePath="C:\\Users\\ZYDR\\Desktop\\20151224-access-ip.txt";//TODO
        try {
            Scanner scanner=new Scanner(new File(filePath));
            int count=0;
            int total=0;
            System.out.println("*****"+filePath+"*****");
            //方法1：不查，批量插
            int count2commit=0;
            List<Ip> ip2Insert=new ArrayList<Ip>(VOLUME_INSERT_IP_NUMBER);
            HashSet<Integer> ip4check=new HashSet<Integer>();
            while (scanner.hasNext()){
                total++;
                String temp=scanner.next();
                int ipId=IpUtil.ip2Int(temp);
                if(!ip4check.contains(ipId)){
                    ip4check.add(ipId);
                    count2commit++;
                    Ip ip=new Ip();
                    ip.setId(ipId);
                    ip.setIp(temp);
                    ip.setIspId(0);//0代表未知运营商
                    ip2Insert.add(ip);
                    count++;
                    System.out.println("*****"+count+"*****");
                    if(count2commit==VOLUME_INSERT_IP_NUMBER){
                        count2commit=0;
                        System.out.println("*****INSERT*****");
                        ipService.insertByVolume(ip2Insert);
                        ip2Insert.clear();
                    }
                }
            }
            System.out.println("*****INSERT*****");
            ipService.insertByVolume(ip2Insert);
            //方法2：一个一查。批量插
//            int count2commit=0;
//            List<Ip> ip2Insert=new ArrayList<Ip>(VOLUME_INSERT_NUMBER);
//            List<Integer> ip4check=new ArrayList<Integer>(VOLUME_INSERT_NUMBER);
//            while (scanner.hasNext()){
//                total++;
//                String temp=scanner.next();
//                int ipId=IpUtil.ip2Int(temp);
//                if(ipService.queryForId(ipId)==null&&!ip4check.contains(ipId)){
//                    ip4check.add(ipId);
//                    count2commit++;
//                    Ip ip=new Ip();
//                    ip.setId(ipId);
//                    ip.setIp(temp);
//                    ip.setIspId(0);//0代表未知运营商
//                    ip2Insert.add(ip);
//                    count++;
//                    System.out.println("*****"+count+"*****");
//                    if(count2commit==VOLUME_INSERT_NUMBER){
//                        count2commit=0;
//                        System.out.println("*****INSERT*****");
//                        ipService.insertByVolume(ip2Insert);
//                        ip2Insert.clear();
//                        ip4check.clear();
//                    }
//                }
//            }
//            System.out.println("*****INSERT*****");
//            ipService.insertByVolume(ip2Insert);
            //方法3：一个一查。一个一插
//            while (scanner.hasNext()){
//                total++;
//                String temp=scanner.next();
//                if(ipService.queryForId(IpUtil.ip2Int(temp))==null){
//                    Ip ip=new Ip();
//                    ip.setId(IpUtil.ip2Int(temp));
//                    ip.setIp(temp);
//                    ip.setIspId(0);//0代表未知运营商
//                    ipService.insert(ip);
//                    count++;
//                    System.out.println("*****"+count+"*****");
//                }
//            }
            System.out.println("*****END*****");
            model.addAttribute("result","共计"+total+"条数据，其中插入"+count+"条数据");
            MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.SUCESS_TITLE,"操作代号：04<br>" +
                    "共计"+total+"条数据<br>"+
                    "其中向t_ip表中插入了"+count+"条数据<br>");
        }
        catch (Exception e){
            model.addAttribute("result",e.getMessage());
            MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.FAILURE_TITLE,"操作代号：04<br>" +e.getMessage());
        }
        return "index";
    }
    @RequestMapping("importTimes")
    public String importTimes(Model model){
        String filePath="C:\\Users\\ZYDR\\Desktop\\20151224-access-ip.txt";//TODO
        try {
            Scanner scanner=new Scanner(new File(filePath));
            int count=0;
            System.out.println("*****"+filePath+"*****");
            int count2commit=0;
            HashMap<Integer,Integer> map2Insert=new HashMap<Integer, Integer>(ipService.count());
            List<Integer> ipList=ipService.queryForAll();
            for (int ip:ipList){
                map2Insert.put(ip,0);
            }
            System.out.println("*****START*****");
            while (scanner.hasNext()){
                count++;
                String temp=scanner.next();
                int ipId=IpUtil.ip2Int(temp);
                map2Insert.put(ipId,map2Insert.get(ipId)+1);

                System.out.println("*****"+count+"*****");
            }
            System.out.println("*****UPDATE*****");
            int i=0;
            HashMap<Integer,Integer> tempMap=new HashMap<Integer, Integer>(VOLUME_INSERT_TIMES_NUMBER);
            for(int key:map2Insert.keySet()){
                i++;
                tempMap.put(key,map2Insert.get(key));
                if(i==VOLUME_INSERT_TIMES_NUMBER){
                    ipService.updateIpTimesByVolume(tempMap);
                    i=0;
                    System.out.println("**********");
                    tempMap.clear();
                }
            }
            ipService.updateIpTimesByVolume(tempMap);
            System.out.println("*****END*****");
            model.addAttribute("result","更新完毕");
            MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.SUCESS_TITLE,"操作代号：07<br>" +
                    "其中向t_ip表中更新了"+count+"条IP数据<br>");
        }
        catch (Exception e){
            model.addAttribute("result",e.getMessage());
            MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.FAILURE_TITLE,"操作代号：07<br>" +e.getMessage());
        }
        return "index";
    }
    @RequestMapping("/analysis")
    public String startAnalysis(Model model){
        //        int startIndex=Integer.MIN_VALUE;//TODO分段查询，用于多台计算机分布式查询
//        int endIndex=Integer.MAX_VALUE;//TODO
//        List<Integer> ipList= (ArrayList<Integer>)ipService.queryWithRange(startIndex,endIndex);

//        //方法1：遍历全部子网，逐一对比
//        List<Integer> ipList=(ArrayList<Integer>)ipService.queryForAll();
//        List<Integer> ispIdList=(ArrayList<Integer>)ispService.queryIspIdList();
//        for(int ip:ipList){
//            for(int ispId:ispIdList){
//                List<IspMask> ispMaskList=(ArrayList<IspMask>)ispMaskService.qureyForIsp(ispId);
//                for(IspMask ispMask:ispMaskList){
//                    if((ispId&ispMask.getMask())==ispMask.getNetId()){
//                        ipService.updateIpInfo(ip,ispId,-1);
//                        break;
//                    }
//                }
//            }
//        }
        //方法2：遍历子网掩码
        //生成子网掩码数组255.255.255.0-255.0.0.0
        System.out.println("*****START*****");
        try{
            int[] masks=new int[17];
            for(int i=0;i<=16;i++){
                masks[i]=-1<<(i+8);
            }
            int count=0;
            //获取待查询的IP地址（int）

            //            方法1：一一查数据库
//            List<Integer> ipList=(ArrayList<Integer>)ipService.queryForAll();
//            for(int ip:ipList){
//                System.out.println("*****"+ip+"*****");
//                for (int mask:masks){
//                    int result=ip&mask;//子网掩码计算
//                    IspMask ispMask=ispMaskService.queryByNetId(result);
//                    if(ispMask!=null){
//                        if (ispMask.getMask()==mask){//子网掩码与本次计算的掩码结果对应
//                            ipService.updateIpInfo(ip,ispMask.getIspId(),-1);
//                            count++;
//                            System.out.println("*****"+count+"*****");
//                            break;
//                        }
//                    }
//                }
//            }
//            方法2：
            // 本地缓存,按照运营商存放相应的掩码信息，
            HashMap<Integer,HashMap<Integer,Integer>> table=new HashMap<Integer, HashMap<Integer, Integer>>(ispService.count());
            table.put(0,ispMaskService.query4isp(0));//未知运营商
            for(Isps isp:Isps.values()){
                table.put(ispService.getIspId(isp.toString()),ispMaskService.query4isp(ispService.getIspId(isp.toString())));
            }
            boolean found=false;
            //全部IP的键值
            List<Integer> ipList=(ArrayList<Integer>)ipService.queryForAll();
            for(int ip:ipList){
                found=false;
                System.out.println("*****"+ip+"*****");
                for (int mask:masks){
                    int result=ip&mask;//子网掩码计算
                    for (int i:table.keySet()){
                        if (table.get(i).containsKey(result)){
                            if (table.get(i).get(result)==mask){//子网掩码与本次计算的掩码结果对应
                                ipService.updateIpInfo(ip,i,-1);
                                count++;
                                System.out.println("*****"+count+"*****");
                                found=true;
                                break;
                            }
                        }
                    }
                    if (found){
                        break;
                    }
                }
            }
            System.out.println("*****END*****");
            model.addAttribute("result","IP共"+ipList.size()+"条<br>"+
                    "其中找到"+count+"条数据的对应运营商<br>");
            MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.SUCESS_TITLE,"操作代号：05<br>" +
                    "IP共"+ipList.size()+"条<br>"+
                    "其中找到"+count+"条数据的对应运营商<br>");
        }
        catch (Exception e){
            model.addAttribute("result",e.getMessage());
            MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.FAILURE_TITLE,"操作代号：05<br>" +e.getMessage());
            return "index";
        }
        return "index";
    }
    @RequestMapping("/getResult")
    public String getResult(Model model){
        String result=new String();
        result+="IP地址数"+ipService.count()+"<br>其中：<br>";
        for (Isps isp:Isps.values()){
            result+=isp.toString()+" 地址数:"+ipService.getNumberByIspId(ispService.getIspId(isp.toString()))+"<br>";
        }
        result+="未知运营商 地址数："+ipService.getNumberByIspId(0)+"<br><br>";

        //流量统计
        result+="访问量总计"+ipService.getFlowByIspId(-1)+"<br>其中：<br>";
        for (Isps isp:Isps.values()){
            result+="来自"+isp.toString()+" :"+ipService.getFlowByIspId(ispService.getIspId(isp.toString()))+"<br>";
        }
        result+="来自未知运营商："+ipService.getFlowByIspId(0)+"<br>";
        infService.updateCensusData(result);
        model.addAttribute("result",result);
        MailUtil.sendMail(MailUtil.DEFAULT_TARGET,MailUtil.SUCESS_TITLE,"操作代号：06<br>"+result);
        return "index";
    }
    private enum Isps{
        DIANXIN("中国电信"),
        LIANTONG("中国移动"),
        YIDONG("中国联通"),
        TIETONG("中国铁通"),
        JIAOYUWANG("中国教育网"),
        KEJIWANG("中国科技网");

        private String isp;
        Isps(String isp) {
            this.isp=isp;
        }

        @Override
        public String toString() {
            return isp;
        }
    }
}
